/**
 * Represents the Willy Wonka character
 * 
 * @author SNelson
 * 
 */
public class WillyWonka extends Thread implements Schedulable
{
	/**
	 * The vending machine that Willy Wonka visits
	 */
	private final VendingMachine machine;
	/**
	 * The scheduler that notifies us of simulated time events
	 */
	private final Scheduler scheduler;

	/**
	 * The hour today that Willy Wonka's appetite will strike
	 */
	private int hourThatAppetiteStrikes = 0;

	/**
	 * Whether or not this thread should stop
	 */
	private boolean stop = false;

	/**
	 * The indention for print statements for Willy Wonka
	 */
	public static final String INDENT = "        ";
	/**
	 * The name used for printing
	 */
	public static final String NAME = "Willy Wonka";

	/**
	 * Constructor
	 * 
	 * @param scheduler
	 *            The scheduler that notifies us of simulated time events
	 * @param machine
	 *            The vending machine that Willy Wonka visits
	 */
	public WillyWonka(Scheduler scheduler, VendingMachine machine)
	{
		this.scheduler = scheduler;
		scheduler.addSchedulable(this);
		this.machine = machine;
		setName(NAME);
	}

	/**
	 * Called when a new day begins
	 * 
	 * @param day
	 *            The day that began
	 */
	@Override
	public void onNewDay(int day)
	{
		hourThatAppetiteStrikes = (int) (Math.random() * 23);
	}

	/**
	 * Called when a new hour begins
	 * 
	 * @param day
	 *            The numeric day in the simulation
	 * @param hour
	 *            The hour of the day
	 */
	@Override
	public void onHour(int day, int hour)
	{
		if (hourThatAppetiteStrikes == hour)
		{
			synchronized (this)
			{
				notifyAll();
			}
		}
	}

	/**
	 * Called when the simulation should end
	 */
	public synchronized void onSimulationEnd()
	{
		scheduler.removeSchedulable(this);
		stop = true;
		notifyAll();
	}

	/**
	 * The body of the thread
	 */
	@Override
	public void run()
	{
		while (!stop)
		{
			synchronized (this)
			{
				try
				{
					wait();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}

				if (stop)
				{
					return;
				}

				VendingMachineTransaction.Builder builder = new VendingMachineTransaction.Builder(
					machine);
				VendingMachineTransaction transaction = builder
					.doSomething(new Runnable()
					{
						@Override
						public void run()
						{
							print("Attempting to purchase candy");
						}
					}).purchaseCandy().build();
				boolean success = machine.executeTransaction(transaction);
				if (success)
				{
					print("The Candy Man Can");
				}
				else
				{
					print("Violet - you're turning violet");
				}
			}
		}
	}

	/**
	 * Prints the given contents formatted for Willy Wonka
	 * 
	 * @param contents
	 *            The contents to print
	 */
	private void print(String contents)
	{
		System.out.println(INDENT + scheduler.getFormattedTime() + " "
			+ getName() + ": " + contents);
	}
}
